home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / tools / classdoc.lha / classdoc / classdoc.awk < prev    next >
Text File  |  1993-08-08  |  6KB  |  286 lines

  1. # classdoc.awk
  2. #
  3. # This awk script tries to produce a manual page from a C++ header file.
  4. # The idea is to make the documentation more readable, without maintaining
  5. # a separate file.  Typical usage:
  6. #
  7. #    gawk -f classdoc.awk list.H | nroff -man
  8. #
  9. # Although the result may not be exactly as intended, nothing in the file
  10. # (except #if, #ifdef, #ifndef, #endif) is supposed to be thrown away.
  11. # Major problem: comments associated with stuff that is saved (typedef, #define,
  12. # etc.), is not saved but appears with some unrelated code.
  13. # Improvemnts are gratefully accepted.
  14. #
  15. # Author: Dag Michael Bruck, Department of Automatic Control, Lund Institute
  16. # of Technology, Box 118, S-221 00 Lund, SWEDEN.  E-mail: dag@control.lth.se
  17. #
  18. # Version: 2.5    Last change: 1990-05-15
  19. #
  20. FNR == 1    {
  21.           "ls -l " FILENAME | getline Date;
  22.           Date = substr(Date, 33, 12);
  23.           print ".TH",FILENAME,"C++","\""Date"\"","\"ClassDoc 2.5\"","\\&";
  24.           Section = "None";
  25.           SubSect = "None";
  26.           ContinueStat = 0;
  27.         }
  28. #
  29. # Stop class ducumentation
  30. #
  31. /CLASSDOC[ \t]+OFF/    {
  32.           while ($0 !~ /CLASSDOC[ \t]+ON/)
  33.             getline;
  34.           getline;
  35.         }
  36. #
  37. # #define macro, placed at end of manual page
  38. #
  39. $1 == "#define" {
  40.           $0 = dropfirst($0);
  41.           match($0, /[A-Za-z0-9_]+(\([^\)]*\))?/);
  42.           save("define", substr($0, RSTART, RLENGTH));
  43.           eatcontinuation();
  44.           next;
  45.         }
  46. #
  47. # #include files, placed at end
  48. #
  49. $1 == "#include" {
  50.           save("include", substr($2, 2, length($2)-2));
  51.           next;
  52.         }
  53. #
  54. # Drop some cpp directives
  55. #
  56. $1 == "#if"    { next; }
  57. $1 == "#ifdef"    { next; }
  58. $1 == "#ifndef"    { next; }
  59. $1 == "#else"    { next; }
  60. $1 == "#elif"    { next; }
  61. $1 == "#endif"    { next; }
  62. #
  63. # Extrnal declarations, placed at end
  64. #
  65. $1 == "extern" {
  66.           save("extern", dropfirst($0));
  67.           next;
  68.         }
  69. #
  70. # Typedef declaration, placed at end
  71. #
  72. $1 == "typedef" {
  73.           save("typedef", dropfirst($0));
  74.           next;
  75.         }
  76. #
  77. # Class declarations, place at end
  78. #
  79. $1 ~ /^class$|^struct$/ && $2 ~ /;$/ {
  80.           save("classdecl", $1 " " substr($2, 1, length($2)-1));
  81.           next;
  82.         }
  83. #
  84. # C++ comment (the /* ... */ variant is not recognized)
  85. #
  86. $1 ~ /^\/\//    { 
  87.           if (!(Section ~ /Description|Class|Code/))
  88.             section("Description", "DESCRIPTION");
  89.           if (InComment == 0) {
  90.             if (Section == "Description")
  91.               print ".fi\n.ft R\n.PP";
  92.             else
  93.               print ".fi\n.ft R\n.sp 0.1v\n.RS 0.25i";
  94.           };
  95.           if (NF == 1)
  96.             print ".PP";
  97.           else {
  98.             match($0, /\/\/[ ]*/);
  99.             print substr($0, RSTART+RLENGTH);
  100.           }
  101.           InComment = 1;
  102.           next;
  103.         }
  104. #
  105. # Class definition
  106. #
  107. $1 ~ /^class$/    && Section != "Class" {
  108.           section("Class", "CLASS " $2);
  109.           if (NF > 4) {
  110.             subsect("Base", "Base class");
  111.             print ".fi\n.ft R";
  112.             for (i=4; i < NF; i++)
  113.               print $i;
  114.             print ".nf\n.ft B";
  115.           };
  116.           next;
  117.         }
  118. #
  119. # Struct definition - almost a class
  120. #
  121. $1 ~ /^struct$/    && Section != "Class" {
  122.           section("Class", "STRUCT " $2);
  123.           subsect("Public", "Public members");
  124.           next;
  125.         }
  126. #
  127. # End of class definition
  128. #
  129. $1 == "};"    {
  130.           Section = "None";
  131.           SubSect = "None";
  132.           InComment = 0;
  133.           next;
  134.         }
  135. #
  136. # Friend declaration, only in classes
  137. #
  138. $1 == "friend"    {
  139.           subsect("Friend", "Friends");
  140.           print dropfirst($0);
  141.           next;
  142.         }
  143. #
  144. # Public, protected and private parts of a class
  145. #
  146. /public:/    {
  147.           subsect("Public", "Public members");
  148.           next;
  149.         }
  150. /protected:/    {
  151.           subsect("Protected", "Protected members");
  152.           next;
  153.         }
  154. /private:/    {
  155.           subsect("Private", "Private members");
  156.           next;
  157.         }
  158. #
  159. # Everything else inside a class (not comments)
  160. #
  161. Section == "Class"    { 
  162.           if (InComment == 1)
  163.             print ".RE\n.PP\n.nf\n.ft B";
  164.           if (NF > 0) print substr($0, index($0, $1));
  165.           if (match($0, /,[ \t]*$/)) {
  166.             if (ContinueStat == 0) print ".RS 1i\n.ft B";
  167.             ContinueStat = 1;
  168.           }
  169.           else if (ContinueStat == 1) {
  170.             print ".RE\n.ft B";
  171.             ContinueStat = 0;
  172.           }
  173.           InComment = 0;
  174.           next;
  175.         }
  176. #
  177. # Blank lines
  178. #
  179. NF == 0        {
  180.           print ".PP"
  181.           if (Section == "Code")
  182.             print ".nf\n.ft B";
  183.           next;
  184.         }
  185. #
  186. # Everything else (outside classes)
  187. #
  188.         {
  189.           if (Section != "Code")
  190.             section("Code", "CODE");
  191.           if (InComment == 1) {
  192.             print ".RE\n.PP\n.nf\n.ft B";
  193.             InComment = 0;
  194.           };
  195.           print;
  196.           next;
  197.         }
  198. #
  199. # Post-processing: list class declarations, external declarations,
  200. # macro definitions and includec files.
  201. #
  202. END        {
  203.           if (issaved("classdecl")) {
  204.             print ".SH CLASS DECLARATIONS\n.nf";
  205.             printsaved("classdecl");
  206.           }
  207.           if (issaved("extern")) {
  208.             print ".SH EXTERNAL DECLARATIONS\n.nf";
  209.             printsaved("extern");
  210.           }
  211.           if (issaved("typedef")) {
  212.             print ".SH TYPE DEFINITIONS\n.nf";
  213.             printsaved("typedef");
  214.           }
  215.           if (issaved("define")) {
  216.             print ".SH DEFINED MACROS\n.nf";
  217.             printsaved("define");
  218.           }
  219.           if (issaved("include")) {
  220.             print ".SH INCLUDED FILES\n.nf";
  221.             printsaved("include");
  222.           }
  223.         }
  224. #
  225. # dropfirst(str) - returns string without its first field
  226. #
  227. function dropfirst(str)
  228. {
  229.   if (match(str, /^[ \t]*[^ \t]*[ \t]+/))
  230.     return substr(str, RLENGTH+1);
  231.   else
  232.     return str;
  233. }
  234. #
  235. # save, ... - functions for saving text in an area, printing it, etc.
  236. #
  237. function save(area, str)
  238. {
  239.   TextCount[area]++;
  240.   TextArea[area, TextCount[area]] = str;
  241. }
  242.  
  243. function issaved(area)
  244. {
  245.   return TextCount[area] > 0;
  246. }
  247.  
  248. function printsaved(area,        i)
  249. {
  250.   for (i = 1; i <= TextCount[area]; i++)
  251.     print TextArea[area, i];
  252. }
  253. #
  254. # section(sect, heading) - change section, no subsection
  255. #
  256. function section(sect, heading)
  257. {
  258.   if (sect != Section) {
  259.     Section = sect;
  260.     print ".SH", heading;
  261.     print ".nf\n.ft B";
  262.     InComment = 0;
  263.   }
  264.   SubSect = "None";
  265. }
  266. #
  267. # subsect(subs, heading) - change subsection
  268. #
  269. function subsect(subs, heading)
  270. {
  271.   if (subs != SubSect) {
  272.     SubSect = subs;
  273.     print ".SS", heading;
  274.     print ".nf\n.ft B";
  275.     InComment = 0;
  276.   }
  277. }
  278. #
  279. # eatcontinuation() - eat continuation lines (preceding line ended in \)
  280. #
  281. function eatcontinuation()
  282. {
  283.   while ($0 ~ /\\$/)
  284.     getline;
  285. }
  286.